#pragma once
#include<memory>
#include<functional>
#include<mutex>
#include <atomic>
#include "ucontext.h"
#include "log.h"
#include "cassert"

namespace sylar{
    using func_t = std::function<void()>;
class Fiber:public std::enable_shared_from_this<Fiber> //安全的生产类指针的智能指针
{
public:
    enum State{
        READY,
        RUNNING,
        TERM
    };//协程的状态
private:
    Fiber(); //主协程，使用private保证只能getthis调用实现单例
public:
    Fiber(func_t func,uint64_t stacksize,bool run_in_sheduler);
    ~Fiber();
public:
    void reset(func_t func);//重置协程函数
    void resume();//恢复协程
    void yield();//暂停协程
    uint64_t getid()const{
        return _id;
    }//获取协程id
    State getstate()const{
        return _state;
    }
public:
    
    static void setthis(Fiber *f);//设置当前运行的协程。

    static std::shared_ptr<Fiber> getthis();//获取当前运行的协程的shared_ptr实例。//兼具初始化主协程的功能

    static void setshedulerfiber(Fiber* f);//设置调度协程，默认主协程

    static uint64_t getfiberid();//获取当前运行的协程的ID。

    static void mainfunc();//协程的主函数，入口点

private:
    uint64_t _id = 0; //协程标识符
    uint64_t _stacksize = 0;
    State _state = READY;
    ucontext_t _ctx;//协程的上下文信息
    void* _stack = nullptr; //协程栈指针
    std::function<void()> _func;//协程任务函数
    bool _if_run_in_sheduler; 
public:
    std::mutex _mtx;
};
}